﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace Common.Extension
{
    /// <summary>
    /// 转换扩展
    /// </summary>
    public static class SafeConvertExtension
    {
        /// <summary>
        /// 返回一个安全值转换对象
        /// </summary>
        /// <param name="obj">任意对象</param>
        /// <example>
        /// <code>
        ///   private void SafeDemo(object obj)
        ///    {
        ///        //安全转换为int
        ///        int intValue = obj.Safe().ToInt32();
        ///
        ///        //安全转换为decimal
        ///        decimal decimalValue = obj.Safe().ToDecimal();
        ///
        ///        //安全转换为DateTime
        ///        DateTime date = obj.Safe().ToDateTime();
        ///
        ///        //其他.......
        ///   }
        /// </code>
        /// </example>
        /// <remarks>
        /// <![CDATA[
        /// 扩展一些常用的判断、数据转换等
        /// ]]>
        /// </remarks>
        /// <returns>返回一个SafeValue安全值对象</returns>
        public static SafeValue Safe(this object obj)
        {
            return new SafeValue(obj);
        }

        ///// <summary>
        ///// 判断是否为Null 如：obj==null
        ///// </summary>
        ///// <param name="obj">任意对象</param>
        ///// <example>
        ///// <code>
        /////         private void IsNullDemo(object obj)
        /////        {
        /////            if (obj.IsNull())
        /////            {
        /////                //obj为null
        /////            }
        /////            else
        /////            {
        /////                //obj不为null
        /////            }
        /////        }
        ///// </code>
        ///// </example>
        ///// <returns>为null返回true，否则false</returns>


        /// <summary>
        /// 转换为指定的数据类型
        /// </summary>
        /// <param name="obj">需要转换的数据</param>
        /// <param name="convertType">需要转换的类型</param>
        /// <example>
        /// <code>
        ///        private void ConvertToDemo()
        ///        {
        ///            object obj = "123";
        ///            int value = obj.ConvertTo(typeof(int));
        ///        }
        /// </code>
        /// </example>
        /// <returns>返回一个convertType类型的值</returns>
        public static object ConvertTo(this object obj, Type convertType)
        {
            if (obj == null || obj == DBNull.Value)
            {
                return null;
            }
            if (convertType.IsClass && convertType != typeof(string))
            {
                return null;
            }
            
            if (convertType.IsGenericType && convertType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                convertType = Nullable.GetUnderlyingType(convertType);
            }

            if (convertType.IsEnum)
            {
                return Enum.Parse(convertType, obj.ToString());
            }

            if (convertType == typeof(bool) && obj.GetType() == typeof(string))
            {
                int boolVal = 0;
                if (int.TryParse(obj.ToString(), out boolVal))
                {
                    obj = boolVal;
                }
            }
            return Convert.ChangeType(obj, convertType);
        }

        /// <summary>
        /// 转换为指定的数据类型
        /// </summary>
        /// <typeparam name="T">指定转换的数据类型</typeparam>
        /// <param name="obj">需要转换的数据</param>
        /// <example>
        /// <code><![CDATA[
        ///        private void ConvertToDemo()
        ///        {
        ///            object obj = "123";
        ///            int value = obj.ConvertTo<int>();
        ///        }
        /// ]]>
        /// </code>
        /// </example>
        /// <returns>返回T</returns>
        public static T ConvertTo<T>(this object obj)
        {
            if (obj == null || object.Equals(obj, DBNull.Value))
            {
                return default(T);
            }

            var type = typeof(T);
            if (type == obj.GetType())
            {
                return (T)obj;
            }
            var value = ConvertTo(obj, type);
            if (value == null)
            {
                return default(T);
            }
            return (T)value;
        }

        /// <summary>
        /// 转换为指定的数据类型
        /// </summary>
        /// <typeparam name="T">指定转换的数据类型</typeparam>
        /// <param name="obj">需要转换的数据</param>
        /// <param name="defaultValu">如果非有效值时，指定的默认值</param>
        /// <example>
        /// <code><![CDATA[
        ///        private void TryConvertToDemo()
        ///        {
        ///            object obj = "123";
        ///            int value = obj.TryConvertTo<int>(1);
        ///        }]]>
        /// </code>
        /// </example>
        /// <returns>返回T</returns>
        public static T TryConvertTo<T>(this T obj, T defaultValu = default(T))
        {
            try
            {
                return ConvertTo<T>(obj);
            }
            catch (Exception)
            {
                return defaultValu;
            }
        }
    }


    /// <summary>
    /// 安全值转换
    /// </summary>
    public class SafeValue
    {
        /// <summary>
        /// 数值
        /// </summary>
        public object Value { get; set; }

        /// <summary>
        /// 实例化一个安全值对象
        /// </summary>
        /// <param name="value"></param>
        public SafeValue(object value)
        {
            Value = value;
        }

        /// <summary>
        /// 转换为ToInt16
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public short ToInt16(short defaultValue = 0)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToInt16(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为ToInt32
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public int ToInt32(int defaultValue = 0)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToInt32(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为ToInt64
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public long ToInt64(long defaultValue = 0)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToInt64(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空的ToInt32
        /// </summary>
        /// <returns></returns>
        public int? ToNullableInt32(int? defaultValue = null)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToInt32(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为decimal
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public decimal ToDecimal(decimal defaultValue = 0)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToDecimal(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空decimal
        /// </summary>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public decimal? ToNullableDecimal(decimal? defaultValue = null)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToDecimal(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为string类型
        /// </summary>
        /// <param name="format">数据格式</param>
        /// <returns></returns>
        public string ToString(string format = "")
        {
            string result = string.Empty;
            try
            {
                if (Value == null)
                {
                    return result;
                }
                if (format == "")
                {
                    result = Value.ToString();
                }
                else
                {
                    result = string.Format("{0:" + format + "}", Value);
                }
                return result;
            }
            catch (Exception)
            {
                return result;
            }
        }

        /// <summary>
        /// 转换为bool类型
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public bool ToBoolean(bool defaultValue = false)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToBoolean(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空DateTime类型
        /// </summary>
        /// <returns></returns>
        public DateTime? ToNullableDateTime()
        {
            try
            {
                if (Value == null)
                {
                    return null;
                }
                return Convert.ToDateTime(Value);
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 转换为DateTime类型
        /// </summary>
        /// <returns></returns>
        public DateTime ToDateTime()
        {
            return ToDateTime(DateTime.MinValue);
        }

        /// <summary>
        /// 转换为DateTime类型
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public DateTime ToDateTime(DateTime defaultValue)
        {
            try
            {
                if (Value == null)
                {
                    return defaultValue;
                }
                return Convert.ToDateTime(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }
    }
}
